// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_BREAKOUT_BOX_MEDIA_STREAM_AUDIO_TRACK_UNDERLYING_SOURCE_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_BREAKOUT_BOX_MEDIA_STREAM_AUDIO_TRACK_UNDERLYING_SOURCE_H_

#include "base/sequence_checker.h"
#include "media/base/audio_parameters.h"
#include "third_party/blink/public/platform/modules/mediastream/web_media_stream_audio_sink.h"
#include "third_party/blink/renderer/modules/breakout_box/frame_queue_underlying_source.h"
#include "third_party/blink/renderer/modules/breakout_box/transferred_frame_queue_underlying_source.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/heap/prefinalizer.h"

namespace blink {

class MediaStreamComponent;
class ReadableStreamTransferringOptimizer;

class MODULES_EXPORT MediaStreamAudioTrackUnderlyingSource
    : public AudioDataQueueUnderlyingSource,
      public WebMediaStreamAudioSink {
  USING_PRE_FINALIZER(MediaStreamAudioTrackUnderlyingSource,
                      DisconnectFromTrack);

 public:
  explicit MediaStreamAudioTrackUnderlyingSource(
      ScriptState*,
      MediaStreamComponent*,
      ScriptWrappable* media_stream_track_processor,
      wtf_size_t queue_size);
  MediaStreamAudioTrackUnderlyingSource(
      const MediaStreamAudioTrackUnderlyingSource&) = delete;
  MediaStreamAudioTrackUnderlyingSource& operator=(
      const MediaStreamAudioTrackUnderlyingSource&) = delete;

  // WebMediaStreamAudioSink
  void OnData(const media::AudioBus& audio_bus,
              base::TimeTicks estimated_capture_time) override;
  void OnSetFormat(const media::AudioParameters& params) override;

  MediaStreamComponent* Track() const { return track_.Get(); }

  std::unique_ptr<ReadableStreamTransferringOptimizer>
  GetTransferringOptimizer();

  void ContextDestroyed() override;
  void Trace(Visitor*) const override;

 private:
  // FrameQueueUnderlyingSource implementation.
  bool StartFrameDelivery() override;
  void StopFrameDelivery() override;

  void DisconnectFromTrack();
  void OnSourceTransferStarted(
      scoped_refptr<base::SequencedTaskRunner> transferred_runner,
      CrossThreadPersistent<TransferredAudioDataQueueUnderlyingSource> source);

  // Only used to prevent the gargabe collector from reclaiming the media
  // stream track processor that created |this|.
  const Member<ScriptWrappable> media_stream_track_processor_;

  Member<MediaStreamComponent> track_;
  bool added_to_track_ = false;

  media::AudioParameters audio_parameters_;
  scoped_refptr<media::AudioBufferMemoryPool> buffer_pool_;

  SEQUENCE_CHECKER(sequence_checker_);
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_BREAKOUT_BOX_MEDIA_STREAM_AUDIO_TRACK_UNDERLYING_SOURCE_H_
